import React, { Suspense, useRef, useEffect, useState } from "react";
import { Canvas, useFrame } from "@react-three/fiber";
import { OrbitControls, useFBX, useGLTF, PerspectiveCamera } from "@react-three/drei";
import * as THREE from "three";

// 可切换的模型文件列表
const modelFiles = [
  { name: "Ready Player Me Avatar", url: "https://models.readyplayer.me/6878b99b4a0f53bfa48db58e.glb", type: "glb" },
  { name: "Silly Dancing", url: "/models/Silly Dancing.fbx", type: "fbx" },
  { name: "Walk Strafe Left", url: "/models/Walk Strafe Left.fbx", type: "fbx" },
  { name: "Jab Cross", url: "/models/Jab Cross.fbx", type: "fbx" },
  { name: "Running Up Stairs", url: "/models/Running Up Stairs.fbx", type: "fbx" }
];

// GLB模型加载与动画播放组件
const GlbModel: React.FC<{ url: string; scale?: number }> = ({ url, scale = 1 }) => {
  const group = useRef<THREE.Group>(null);
  // 加载GLB模型
  const { scene, animations } = useGLTF(url);
  const mixer = useRef<THREE.AnimationMixer>();
  const actionRef = useRef<THREE.AnimationAction | null>(null);

  // 每次模型变化时，播放第一个动画片段
  useEffect(() => {
    if (animations && animations.length > 0 && group.current) {
      mixer.current = new THREE.AnimationMixer(group.current);
      if (actionRef.current) actionRef.current.stop();
      const action = mixer.current.clipAction(animations[0]);
      action.play();
      actionRef.current = action;
    }
    return () => {
      mixer.current?.stopAllAction();
    };
  }, [animations]);

  // 驱动动画播放
  useFrame((_, delta) => {
    mixer.current?.update(delta);
  });

  // 设置模型阴影属性      
  scene.traverse((child: THREE.Object3D) => {
    if ((child as THREE.Mesh).isMesh) {
      const mesh = child as THREE.Mesh;
      mesh.castShadow = true;
      mesh.receiveShadow = true;
    }
  });

  // 渲染GLB模型
  return <primitive ref={group} object={scene} scale={scale} position={[0, -0.8, 0]} />;
};

// 单个FBX模型加载与动画播放组件
const FbxModel: React.FC<{ url: string; scale?: number }> = ({ url, scale = 0.008 }) => {
  const group = useRef<THREE.Group>(null);
  // 加载FBX模型
  const fbx = useFBX(url);
  const mixer = useRef<THREE.AnimationMixer>();
  const actionRef = useRef<THREE.AnimationAction | null>(null);

  // 每次FBX模型变化时，播放第一个动画片段
  useEffect(() => {
    if (fbx.animations && fbx.animations.length > 0 && group.current) {
      mixer.current = new THREE.AnimationMixer(group.current);
      if (actionRef.current) actionRef.current.stop();
      const action = mixer.current.clipAction(fbx.animations[0]);
      action.play();
      actionRef.current = action;
    }
    return () => {
      mixer.current?.stopAllAction();
    };
  }, [fbx]);

  // 驱动动画播放
  useFrame((_, delta) => {
    mixer.current?.update(delta);
  });

  // 设置模型阴影属性      
  fbx.traverse((child: THREE.Object3D) => {
    if ((child as THREE.Mesh).isMesh) {
      const mesh = child as THREE.Mesh;
      mesh.castShadow = true;
      mesh.receiveShadow = true;
    }
  });

  // 渲染FBX模型
  return <primitive ref={group} object={fbx} scale={scale} position={[0, -0.8, 0]} />;
};

// 场景组件，包含灯光、地面、相机、模型
const Scene: React.FC<{ modelUrl: string; modelType: string; isDark: boolean }> = ({ modelUrl, modelType, isDark }) => (
  <>
    <PerspectiveCamera makeDefault position={[0, 0.5, 3]} fov={40} />
    <ambientLight intensity={isDark ? 0.5 : 0.7} />
    <directionalLight
      position={[2, 5, 2]}
      intensity={isDark ? 1.0 : 1.2}
      castShadow
      shadow-mapSize-width={1024}
      shadow-mapSize-height={1024}
    />

    <Suspense fallback={null}>
      {modelType === 'glb' ? (
        <GlbModel url={modelUrl} />
      ) : (
        <FbxModel url={modelUrl} />
      )}
    </Suspense>
    <OrbitControls enablePan={false} maxPolarAngle={Math.PI / 2} />
  </>
);

// 主页面组件，支持模型动画切换
const Indextow3D: React.FC<{ height?: number }> = ({ height = 320 }) => {
  const [selectedModel, setSelectedModel] = useState(modelFiles[0]);
  
  // 获取主题状态，优先使用本地存储
  const getThemeState = () => {
    const localThemeMode = localStorage.getItem('themeMode') || 'system';
    let currentTheme = localThemeMode;
    
    // 如果设置为跟随系统，则检测系统主题
    if (localThemeMode === 'system') {
      currentTheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
    }
    
    const bodyTheme = document.body.dataset.theme || 
                     (document.body.classList.contains('dark') ? 'dark' : 'light');
    const finalTheme = currentTheme || bodyTheme;
    return finalTheme === 'dark';
  };
  
  const [isDark, setIsDark] = useState(getThemeState());
  
  useEffect(() => {
    const checkTheme = () => {
      const newIsDark = getThemeState();
      console.log('数字人组件主题检测:', newIsDark ? '暗色' : '亮色');
      setIsDark(newIsDark);
    };
    
    // 初始检查
    checkTheme();
    
    const observer = new MutationObserver(checkTheme);
    observer.observe(document.body, { attributes: true, attributeFilter: ['class', 'data-theme'] });
    
    // 监听localStorage变化
    const handleStorageChange = () => {
      checkTheme();
    };
    window.addEventListener('storage', handleStorageChange);
    
    // 监听系统主题变化
    const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
    const handleSystemThemeChange = () => {
      const localThemeMode = localStorage.getItem('themeMode') || 'system';
      if (localThemeMode === 'system') {
        checkTheme();
      }
    };
    mediaQuery.addEventListener('change', handleSystemThemeChange);
    
    return () => {
      observer.disconnect();
      window.removeEventListener('storage', handleStorageChange);
      mediaQuery.removeEventListener('change', handleSystemThemeChange);
    };
  }, []);

  const handleModelChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
    const selectedUrl = e.target.value;
    const model = modelFiles.find(m => m.url === selectedUrl) || modelFiles[0];
    setSelectedModel(model);
  };

  return (
    <div>
      <div className="indextow-select-bar" style={{ textAlign: 'center', marginBottom: 8 }}>
        <span className="indextow-select-title">选择数字人：</span>
        <select
          value={selectedModel.url}
          onChange={handleModelChange}
          style={{ fontSize: 14, padding: '2px 8px', borderRadius: 4 }}
        >
          {modelFiles.map(model => (
            <option value={model.url} key={model.url}>{model.name}</option>
          ))}
        </select>
        <div style={{ marginTop: 8, fontSize: 12, color: '#666' }}>
          当前主题: {isDark ? '暗色' : '亮色'} | 背景: 透明 | 模型类型: {selectedModel.type.toUpperCase()}
        </div>
      </div>
      <div className="indextow-3d-area" style={{ width: '100%', height }}>
        <div style={{ 
          width: '100%', 
          height: '100%', 
          background: 'transparent',
          borderRadius: 0,
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center'
        }}>
          <Canvas shadows style={{ 
            width: "100%", 
            height: '100%', 
            background: "transparent", 
            borderRadius: 0 
          }}>
            <Scene modelUrl={selectedModel.url} modelType={selectedModel.type} isDark={isDark} />
          </Canvas>
        </div>
      </div>
    </div>
  );
};

export default Indextow3D;